#pragma
#include<iostream>
#include<string>
#include<cstring>
#include<functional>
#include<pthread.h>
#include<cassert>
#include<unistd.h>

//对原生线程库pthread进行封装
//以后可以直接用，类似c++的线程操作接口，这样调用线程不用那么麻烦


class Thread; // 前置声明
//用于调用线程函数的上下文结构
class Context
{
public:
    Context()
    :_this(nullptr), _args(nullptr)
    {}
    ~Context()
    {}

    Thread* _this;
    void* _args;
};

class Thread
{
    typedef std::function<void*(void*)> func_t; //定义一个函数类型，返回值void* 参数void*
    const int n = 1024;
public:
    Thread(func_t func, void* args, int number)
    :_func(func), _args(args)
    {
        //这里用c++很简单，这里用c不用c++是因为这种偏底层的都是c/c++混编，要多熟练一下
        char buffer[n];
        snprintf(buffer, sizeof buffer, "thread-%d", number);
        _name = buffer;

        Context* ctx = new Context();
        ctx->_this = this;
        ctx->_args = _args;
        int n = pthread_create(&_tid, nullptr, start_routine, (void*)ctx);
        assert(n == 0);
        (void)n;
    }

    //这个函数不是给外部使用的
    void* run(void* args)
    {
        return _func(args);
    }

    //类内方法都有一个默认的this指针形参，因此要在类中调用新线程执行的函数，就要static
    static void* start_routine(void* args)
    {
        Context* ctx = static_cast<Context*>(args);
        void* ret = ctx->_this->run(ctx->_args);

        return ret; //线程终止
    }

    void start()
    {

    }

    void join()
    {
        int n = pthread_join(_tid, nullptr); //暂时不考虑函数返回值的问题
        assert(n == 0);
        (void)n;
    }

    ~Thread()
    {}

private:
    std::string _name;
    pthread_t _tid;
    func_t _func; // 未来新线程调用的函数  
    void* _args;

};

